package world.criver.h50529.controller;

import com.fazecast.jSerialComm.SerialPort;
import javafx.application.Platform;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import world.criver.h50529.data.daControllers;
import world.criver.h50529.data.daData;
import world.criver.h50529.enums.enumComType;
import world.criver.h50529.function.*;
import world.criver.h50529.module.moEvent;

import java.net.URL;
import java.util.ResourceBundle;

public class conPage3Add implements Initializable {
    public VBox tcp_udp_list;
    public VBox com3_list;
    public TextField name;
    public ComboBox<String> communication_mode;
    public VBox list;
    public Label name_tip;
    public TextField ip1;
    public TextField ip2;
    public TextField ip3;
    public TextField ip4;
    public TextField port;
    public ComboBox<String> serials;
    public ComboBox<String> baud_rate;
    public ComboBox<Integer> num_data_bit;
    public ComboBox<Float> num_stop_bit;
    public ComboBox<String> parity;
    public TextArea send_message;
    public RadioButton message_type_str;
    public RadioButton message_type_hex;
    public Label tip;
    public VBox wol_list;
    public HBox data_type_list;
    public HBox data_list;
    public TextField mac_0;
    public TextField mac_1;
    public TextField mac_2;
    public TextField mac_3;
    public TextField mac_4;
    public TextField mac_5;

    private final int[] baud_rate_list={75,110,134,150,300,600,1200,1800,2400,4800,7200,9600,14400,19200,38400,57600,115200,128000};
    private final int[] num_data_bit_list={1,2,3,4,5,6,7,8};
    private final float[] num_stop_bit_list={1,1.5f,2};
    private final String[] parity_list={"无校验","奇校验","偶校验","1校验","0校验"};

    private funMessageFormat funMessageFormat=new funMessageFormat();
    private boolean is_update=false;

    public void changeMode() {
        list.getChildren().remove(tcp_udp_list);
        list.getChildren().remove(com3_list);
        list.getChildren().remove(data_list);
        list.getChildren().remove(data_type_list);
        list.getChildren().remove(wol_list);
        String mode=communication_mode.getSelectionModel().getSelectedItem();
        if(mode.equals(enumComType.com3.name().toUpperCase())){//串口
            list.getChildren().add(2,com3_list);
            list.getChildren().add(3,data_list);
            list.getChildren().add(4,data_type_list);
        }else if(mode.equals(enumComType.tcp.name().toUpperCase())){//tcp
            list.getChildren().add(2,tcp_udp_list);
            list.getChildren().add(3,data_list);
            list.getChildren().add(4,data_type_list);
        }else if(mode.equals(enumComType.udp.name().toUpperCase())){//udp
            list.getChildren().add(2,tcp_udp_list);
            list.getChildren().add(3,data_list);
            list.getChildren().add(4,data_type_list);
        }else if(mode.equals(enumComType.wol.name().toUpperCase())){//wol
            list.getChildren().add(2,tcp_udp_list);
            list.getChildren().add(3,wol_list);
        }else tip.setText("未找到类型");
    }
    public void ini(){
        is_update=false;
        name.setText("");
        name.setEditable(true);
        communication_mode.getSelectionModel().select(0);
        changeMode();
        ip1.setText("");
        ip2.setText("");
        ip3.setText("");
        ip4.setText("");
        port.setText("");
        new funSerial().iniSerialPorts();
        serials.getItems().clear();
        for(SerialPort sp: daData.serialPorts)serials.getItems().add(sp.getSystemPortName());
        serials.getSelectionModel().select(0);
        baud_rate.getSelectionModel().select("9600");
        num_data_bit.getSelectionModel().select(0);
        num_stop_bit.getSelectionModel().select(0);
        parity.getSelectionModel().select(0);
        onChangeSerial();
        send_message.setText("");
        message_type_str.setSelected(true);
        message_type_hex.setSelected(false);
        name_tip.setText("");
        tip.setText("");
        mac_0.setText("");
        mac_1.setText("");
        mac_2.setText("");
        mac_3.setText("");
        mac_4.setText("");
        mac_5.setText("");
    }
    public void load(moEvent event){
        is_update=true;
        name.setText(event.getName());
        name.setEditable(false);
        communication_mode.getSelectionModel().select(event.getCommunication_mode());
        changeMode();
        String[] ips=event.getIp().split("\\.");
        ip1.setText(ips[0]);
        ip2.setText(ips[1]);
        ip3.setText(ips[2]);
        ip4.setText(ips[3]);
        port.setText(event.getPort()+"");
        new funSerial().iniSerialPorts();
        serials.getItems().clear();
        for(SerialPort sp: daData.serialPorts)serials.getItems().add(sp.getSystemPortName());
        serials.getSelectionModel().select(event.getSerial());
//        if(!serials.getSelectionModel().getSelectedItem().equals(event.getSerial())){
//            serials.getItems().add(event.getSerial());
//            serials.getSelectionModel().select(event.getSerial());
//        }
        baud_rate.getSelectionModel().select(event.getBaud_rate()+"");
        num_data_bit.getSelectionModel().select(event.getNum_data_bit()-1);
        num_stop_bit.getSelectionModel().select(event.getNum_stop_bit());
        parity.getSelectionModel().select(event.getParity());
        send_message.setText(event.getSend_data());
        if(event.getMessage_type().equalsIgnoreCase("hex")){
            onSelectedMessageTypeHex();
            message_type_hex.setSelected(true);
        }
        else{
            message_type_str.setSelected(true);
            message_type_hex.setSelected(false);
        }
        name_tip.setText("");
        tip.setText("");
        if(event.getMac()==null)return;
        String[] macs=event.getMac().split(":");
        if(macs.length>0)mac_0.setText(macs[0]);
        if(macs.length>1)mac_0.setText(macs[1]);
        if(macs.length>2)mac_0.setText(macs[2]);
        if(macs.length>3)mac_0.setText(macs[3]);
        if(macs.length>4)mac_0.setText(macs[4]);
        if(macs.length>5)mac_0.setText(macs[5]);
    }
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        Platform.runLater(()->{
            communication_mode.getItems().add(enumComType.com3.name().toUpperCase());
            communication_mode.getItems().add(enumComType.tcp.name().toUpperCase());
            communication_mode.getItems().add(enumComType.udp.name().toUpperCase());
            communication_mode.getItems().add(enumComType.wol.name().toUpperCase());
            communication_mode.getSelectionModel().select(0);
            for(int i:baud_rate_list)baud_rate.getItems().add(i+"");
            baud_rate.getSelectionModel().select(9600);
            for(int i:num_data_bit_list)num_data_bit.getItems().add(i);
            num_data_bit.getSelectionModel().select(0);
            for(float i:num_stop_bit_list)num_stop_bit.getItems().add(i);
            num_stop_bit.getSelectionModel().select(0);
            for(String i:parity_list)parity.getItems().add(i);
            parity.getSelectionModel().select(0);
            changeMode();
            name.setTextFormatter(new TextFormatter<String>(e->{
                name_tip.setText("");
                String n=e.getControlNewText();
                if(n.isEmpty())return e;
                if(n.matches("^[\\p{L}\\p{N}]*$") && n.length()<=64){
                    if(!is_update)for(moEvent mo:daData.events)if(mo.getName().equals(n))name_tip.setText("名称已存在");
                    return e;
                }
                return null;
            }));
//            setTextFieldOnlyNumber(ip1,255);
//            setTextFieldOnlyNumber(ip2,255);
//            setTextFieldOnlyNumber(ip3,255);
//            setTextFieldOnlyNumber(ip4,255);
//            setTextFieldOnlyNumber(port,65535);
//            setTextFieldNumberAndLetter(mac_0,2);
//            setTextFieldNumberAndLetter(mac_1,2);
//            setTextFieldNumberAndLetter(mac_2,2);
//            setTextFieldNumberAndLetter(mac_3,2);
//            setTextFieldNumberAndLetter(mac_4,2);
//            setTextFieldNumberAndLetter(mac_5,2);
        });
    }

    public void onTest() {
        if(!testInput())return;
        String mode=communication_mode.getSelectionModel().getSelectedItem();
        if(mode.equals(enumComType.com3.name().toUpperCase())){
            tip.setText(new funSerial().send(getMoEvent()));
        }else if(mode.equals(enumComType.tcp.name().toUpperCase())){
            tip.setText(new funTcp().send(getMoEvent()));
        }else if(mode.equals(enumComType.udp.name().toUpperCase())){
            tip.setText(new funUdp().send(getMoEvent()));
        }else if(mode.equals(enumComType.wol.name().toUpperCase())){
            tip.setText(new funWol().send(getMoEvent()));
        }else{
            tip.setText("未找到类型");
        }
    }
    private moEvent getMoEvent(){
        moEvent mo=new moEvent();
        mo.setName(name.getText());
        mo.setCommunication_mode(communication_mode.getSelectionModel().getSelectedItem());
        mo.setIp(Integer.parseInt("0"+ip1.getText())+"."+Integer.parseInt("0"+ip2.getText())+"."+Integer.parseInt("0"+ip3.getText())+"."+Integer.parseInt("0"+ip4.getText()));
        mo.setPort(Integer.parseInt("0"+port.getText()));
        mo.setSerial(serials.getSelectionModel().getSelectedItem());
        mo.setBaud_rate(Integer.parseInt(baud_rate.getSelectionModel().getSelectedItem()));
        mo.setNum_data_bit(num_data_bit.getSelectionModel().getSelectedItem());
        mo.setNum_stop_bit(num_stop_bit.getSelectionModel().getSelectedItem());
        mo.setParity(parity.getSelectionModel().getSelectedItem());
        mo.setMessage_type(message_type_str.isSelected()?"str":"hex");
        mo.setSend_data(send_message.getText());
        mo.setMac(mac_0.getText()+":"+mac_1.getText()+":"+mac_2.getText()+":"+mac_3.getText()+":"+mac_4.getText()+":"+mac_5.getText());
        return mo;
    }

    public void onSave() {
        if(!testInput())return;
        moEvent mo=getMoEvent();
        if(is_update){
            for(moEvent m:daData.events){
                if(m.getName().equals(mo.getName())){
                    daData.events.remove(m);
                    break;
                }
            }
        }
        daData.events.add(mo);
        new funFiles().saveEvent(mo);
        daControllers.master.onMenuItem3();
    }
    private boolean testInput(){
        name_tip.setText("");
        tip.setText("");
        String mode=communication_mode.getSelectionModel().getSelectedItem();
        if(mode.equals(enumComType.com3.name().toUpperCase())||mode.equals(enumComType.tcp.name().toUpperCase())||mode.equals(enumComType.udp.name().toUpperCase())) {
            if (!is_update) {
                String name = this.name.getText();
                if (name.isEmpty()) {
                    name_tip.setText("名称不得为空");
                    return false;
                }
                if (name.length() > 64) {
                    name_tip.setText("长度不得超过64位");
                    return false;
                }
                for (moEvent mo : daData.events)
                    if (mo.getName().equals(name)) {
                        name_tip.setText("名称已存在");
                        return false;
                    }
            }
            if (send_message.getText().isEmpty()) {
                tip.setText("发送信息不得为空");
                return false;
            }
        }
        if(mode.equals(enumComType.tcp.name().toUpperCase())||mode.equals(enumComType.udp.name().toUpperCase())||mode.equals(enumComType.wol.name().toUpperCase())){
            if(ip1.getText().isEmpty()||ip2.getText().isEmpty()||ip3.getText().isEmpty()||ip4.getText().isEmpty()||port.getText().isEmpty()){
                tip.setText("ip地址错误");
                return false;
            }
        }
        if(mode.equals(enumComType.wol.name().toUpperCase())){
            if(mac_0.getText().isEmpty()||mac_1.getText().isEmpty()||mac_2.getText().isEmpty()||mac_3.getText().isEmpty()||mac_4.getText().isEmpty()||mac_5.getText().isEmpty()){
                tip.setText("mac地址未填写或填写错误");
                return false;
            }
        }
        return true;
    }

    public void onChangeSerial() {
        String name=serials.getSelectionModel().getSelectedItem();
        for(SerialPort sp:daData.serialPorts)if(sp.getSystemPortName().equals(name)){
            baud_rate.getSelectionModel().select(sp.getBaudRate()+"");
            num_data_bit.getSelectionModel().select(sp.getNumDataBits()-1);
            num_stop_bit.getSelectionModel().select(sp.getNumStopBits()-1);
            parity.getSelectionModel().select(sp.getParity());
            return;
        }
    }
    private void setTextFieldOnlyNumber(TextField tf,int max){
        tf.setTextFormatter(new TextFormatter<Integer>(e->{
            String a=e.getControlNewText();
            if(a.isEmpty())return e;//56-4a-65-98-54-65
            if(a.contains(".")||a.contains(":")){
                String[] ips=a.split(":")[0].split("\\.");//192.168.0.192:12345
                String port=a.contains(":")?a.split(":")[1]:"";
                if(ips.length>0&&tf!=ip1&&ips[0].matches("\\d+"))if(Integer.parseInt(ips[0])<=255)ip1.setText(ips[0]);
                if(ips.length>1&&tf!=ip2&&ips[1].matches("\\d+"))if(Integer.parseInt(ips[1])<=255)ip2.setText(ips[1]);
                if(ips.length>2&&tf!=ip3&&ips[2].matches("\\d+"))if(Integer.parseInt(ips[2])<=255)ip3.setText(ips[2]);
                if(ips.length>3&&tf!=ip4&&ips[3].matches("\\d+"))if(Integer.parseInt(ips[3])<=255)ip4.setText(ips[3]);
                if(tf!=this.port&&port.matches("\\d+"))if(Integer.parseInt(port)<=65535)this.port.setText(port);
                if(tf==ip1&&ips.length>0&&ips[0].matches("\\d+")){if(Integer.parseInt(ips[0])<=255)e.setText(ips[0]);else return null;}
                else if(tf==ip2&&ips.length>1&&ips[1].matches("\\d+")){if(Integer.parseInt(ips[1])<=255)e.setText(ips[1]);else return null;}
                else if(tf==ip3&&ips.length>2&&ips[2].matches("\\d+")){if(Integer.parseInt(ips[2])<=255)e.setText(ips[2]);else return null;}
                else if(tf==ip4&&ips.length>3&&ips[3].matches("\\d+")){if(Integer.parseInt(ips[3])<=255)e.setText(ips[3]);else return null;}
                else if(tf==this.port&&port.matches("\\d+")){if(Integer.parseInt(port)<=65536)e.setText(port);else return null;}
                else return null;
                return e;
            }
            if(a.matches("\\d+")){
                if(!e.getControlNewText().isEmpty())if(Integer.parseInt(e.getControlNewText())>max)return null;
                return e;
            }
            return null;
        }));
    }
    private void setTextFieldNumberAndLetter(TextField tf,int length){
        tf.setTextFormatter(new TextFormatter<Integer>(e->{
            String a=e.getControlNewText();
            if(a.isEmpty())return e;
            if(a.contains(":")||a.contains("-")){
                a=a.replaceAll(" ","");
                String[] q=a.contains(":")?a.split(":"):a.split("-");
                if(q.length>0&&tf!=mac_0&&q[0].matches("^[0-9a-zA-Z]{2}$"))mac_0.setText(q[0]);
                if(q.length>1&&tf!=mac_1&&q[1].matches("^[0-9a-zA-Z]{2}$"))mac_1.setText(q[1]);
                if(q.length>2&&tf!=mac_2&&q[2].matches("^[0-9a-zA-Z]{2}$"))mac_2.setText(q[2]);
                if(q.length>3&&tf!=mac_3&&q[3].matches("^[0-9a-zA-Z]{2}$"))mac_3.setText(q[3]);
                if(q.length>4&&tf!=mac_4&&q[4].matches("^[0-9a-zA-Z]{2}$"))mac_4.setText(q[4]);
                if(q.length>5&&tf!=mac_5&&q[5].matches("^[0-9a-zA-Z]{2}$"))mac_5.setText(q[5]);
                if(tf==mac_0&&q.length>0&&q[0].matches("^[0-9a-zA-Z]{2}$"))e.setText(q[0]);
                else if(tf==mac_1&&q.length>1&&q[1].matches("^[0-9a-zA-Z]{2}$"))e.setText(q[1]);
                else if(tf==mac_2&&q.length>2&&q[2].matches("^[0-9a-zA-Z]{2}$"))e.setText(q[2]);
                else if(tf==mac_3&&q.length>3&&q[3].matches("^[0-9a-zA-Z]{2}$"))e.setText(q[3]);
                else if(tf==mac_4&&q.length>4&&q[4].matches("^[0-9a-zA-Z]{2}$"))e.setText(q[4]);
                else if(tf==mac_5&&q.length>5&&q[5].matches("^[0-9a-zA-Z]{2}$"))e.setText(q[5]);
                else return null;
                return e;
            }
            if(a.length()>length)return null;
            if(a.matches("[0-9a-zA-Z]*"))return e;
            return null;
        }));
    }

    public void onSelectedMessageTypeStr() {
        message_type_hex.setSelected(false);
//        send_message.setText(funMessageFormat.hexToString(send_message.getText().replaceAll(" ","")));
    }
    public void onSelectedMessageTypeHex() {
        message_type_str.setSelected(false);
//        String a=funMessageFormat.stringToHex(send_message.getText());
//        String b="";
//        for(int i=0;i<a.length()/2;i++)b+=a.substring(i*2,i*2+2)+" ";
//        send_message.setText(b);
    }
}
